//
// Created by twetec on 25-7-10.
//

#ifndef NETWORK_PROBER_UTILS_SNOWFLAKE_UUID_GENERATOR_H
#define NETWORK_PROBER_UTILS_SNOWFLAKE_UUID_GENERATOR_H

namespace network_prober::utils
{
class SnowflakeUUIDGenerator
{
public:
    uint64_t generate();    // 生成UUID
    static SnowflakeUUIDGenerator &getInstance(); // 获取实例

private:
    uint64_t _currentTimestamp() const;
    uint64_t _waitNextMillis(uint64_t lastTimestamp);

    SnowflakeUUIDGenerator();  // 构造函数私有化
    ~SnowflakeUUIDGenerator(); // 析构函数私有化

    SnowflakeUUIDGenerator(const SnowflakeUUIDGenerator &) = delete;            // 禁用默认拷贝构造函数（初始化赋值时调用）
    SnowflakeUUIDGenerator &operator=(const SnowflakeUUIDGenerator &) = delete; // 禁用默认拷贝赋值（初始化后，再赋值时调用）

    SnowflakeUUIDGenerator(SnowflakeUUIDGenerator &&) = delete;            // 针对右值
    SnowflakeUUIDGenerator &operator=(SnowflakeUUIDGenerator &&) = delete; // 针对右值

private:
    const uint64_t m_twepoch = 1609459200000ULL;  // 2021-01-01 00:00:00 UTC
    const uint64_t m_unixEpoch = 0ULL;  // Unix时间戳起点：1970-01-01 00:00:00 UTC
    const uint64_t m_workerIdBits = 5;
    const uint64_t m_datacenterIdBits = 5;
    const uint64_t m_maxWorkerId = (1ULL << m_workerIdBits) - 1;
    const uint64_t m_maxDatacenterId = (1ULL << m_datacenterIdBits) - 1;
    const uint64_t m_sequenceBits = 12;
    const uint64_t m_workerIdShift = m_sequenceBits;
    const uint64_t m_datacenterIdShift = m_sequenceBits + m_workerIdBits;
    const uint64_t m_timestampLeftShift = m_sequenceBits + m_workerIdBits + m_datacenterIdBits;
    const uint64_t m_sequenceMask = (1ULL << m_sequenceBits) - 1;

    uint16_t m_datacenterId;
    uint16_t m_workerId;
    uint64_t m_sequence;
    uint64_t m_lastTimestamp;
    std::mutex m_mutex;
};

}

#endif //NETWORK_PROBER_UTILS_SNOWFLAKE_UUID_GENERATOR_H
